﻿using System;
using System.Collections.Generic;
using System.Text;
using Lswweb.Model;
using Lswweb.Domain;
using Lswweb.IDAL;
using Lswweb.Common;

namespace Lswweb.Domain
{
    public class Orders
    {
        private static IOrders orderDAL = DALFactory.CreateOrdersDAL();

        public static OrderInfo GetOrder(int orderId)
        {
            return orderDAL.GetOrder(orderId);
        }

        public static IList<OrderItemInfo> GetOrderItems(int orderId)
        {
            return orderDAL.GetOrderItems(orderId);
        }

        public static IList<OrderInfo> GetOrders(int userId,OrderStatus status,int pageSize,int pageIndex,out int totalCount)
        {
            return orderDAL.GetOrders(userId, status, pageSize, pageIndex, out totalCount);
        }
        public static IList<OrderInfo> GetOrders(string searchKey, Pair<DateTime?> dateRange, OrderStatus? status, int pageSize, int pageIndex, out int record)
        {
            return orderDAL.GetOrders(searchKey, dateRange,status, pageSize, pageIndex, out record);
        }

        public static void Insert(OrderInfo orderInfo,int cityId)
        {
            if (orderInfo == null)
                SiteContext.RenderMessage(ExceptionType.UnknownError);

            IShoppingCart shoppingCart = ShoppingCartFactory.GetShoppingCart();

            orderInfo.OrderItems = GetOrderItemsByCartItems(shoppingCart.Items);
            orderInfo.ProductPrices = shoppingCart.TotalPrice;
            orderInfo.LogisticsPrices = AreaExpressDeliveryExpressions.CountExpressFee(cityId,orderInfo.LtsType, shoppingCart.TotalWeight,orderInfo.TotalPrices);
            orderInfo.Address = orderInfo.Address;
            orderInfo.CityId = cityId;

            int orderId= orderDAL.Insert(orderInfo);
            if (orderId <= 0)
            {
                SiteContext.RenderMessage(ExceptionType.UnknownError);
            }
            else
            {
                orderInfo.OrderItems.ForEach(item =>
                {
                    Products.AddSale(item.ProductId, item.Quantity);
                });

                shoppingCart.Clear();
                UserInfo userInfo = Users.GetUser(orderInfo.UserId);
                orderInfo.Id = orderId;
                Email.SendMail(userInfo.Email, orderInfo);
                SiteContext.Current.Context.Response.Redirect(SiteUrls.Urls.OrderEnd(orderId),true);
            }
        }

        public static void Delete(int orderId)
        {
            bool label=orderDAL.Delete(orderId);
            if (label)
                SiteContext.RenderMessage(ExceptionType.HandleSuccess);
            else
                SiteContext.RenderMessage(ExceptionType.UnknownError); 
        }

        public static void UpdateStatus(int orderId, OrderStatus status)
        {
            UpdateStatus(orderId,status,false);
        }
        public static void UpdateStatus(int orderId, OrderStatus status,bool validated)
        {
            //未登录，不可状态进行修改
            if (!SiteContext.Current.Context.User.Identity.IsAuthenticated && !validated)
                return;

            //不是管理员只可以把订单状态修改为“确认收货”
            if (!validated && !SiteContext.Current.User.IsAdmin)
            {
                if (status != OrderStatus.ConfirmationReceipt)
                    return;
            }

            OrderStatus oldStatus = orderDAL.GetStatus(orderId);
            if (status != OrderStatus.AbnormityEnd
                && status!= OrderStatus.ConfirmationReceipt
                //状态只可正向修改并且每次修改只能进位一个状态，不可逆向修改
                //&& (int)status != (Convert.ToInt32(oldStatus) + 1)
                //状态只可正向修改，不可逆向修改
                && status.As<int>() <= oldStatus.As<int>())
            {
                return;
            }

            bool label = orderDAL.Update(orderId, status);
            if (label)
                SiteContext.RenderMessage(ExceptionType.HandleSuccess);
            else
                SiteContext.RenderMessage(ExceptionType.UnknownError);
        }

        public static void UpdatePayment(PaymentInfo paymentInfo)
        {
            if (paymentInfo.OrderId <= 0)
                SiteContext.RenderMessage(ExceptionType.UnknownError);

            bool label = orderDAL.UpdatePayment(paymentInfo);
            if (label)
            {
                OrderStatus status = orderDAL.GetStatus(paymentInfo.OrderId);
                if (status == OrderStatus.WaitPayment)
                    label = orderDAL.Update(paymentInfo.OrderId, OrderStatus.WaitConfirmation);
            }

            if (label)
                SiteContext.RenderMessage(ExceptionType.HandleSuccess);
            else
                SiteContext.RenderMessage(ExceptionType.UnknownError);
        }

        public static void UpdateLogiscits(LogisticsInfo logisticsInfo)
        {
            if(logisticsInfo.OrderId<=0)
                SiteContext.RenderMessage(ExceptionType.UnknownError);

            bool label = orderDAL.UpdateLogistics(logisticsInfo);
            if (label)
            {
                OrderStatus status = orderDAL.GetStatus(logisticsInfo.OrderId);
                //因为一些订单货到付款 ，所以在新订单状态就需要发货
                if (status == OrderStatus.WaitPayment)
                {
                    orderDAL.Update(logisticsInfo.OrderId, OrderStatus.WaitConfirmation);
                    orderDAL.Update(logisticsInfo.OrderId, OrderStatus.InStock);
                }

                if (status == OrderStatus.InStock || status == OrderStatus.WaitPayment)
                    label = orderDAL.Update(logisticsInfo.OrderId, OrderStatus.WaitReceive);
            }

            if (label)
                SiteContext.RenderMessage(ExceptionType.HandleSuccess);
            else
                SiteContext.RenderMessage(ExceptionType.UnknownError);
        }

        private static IList<OrderItemInfo> GetOrderItemsByCartItems(ICollection<IShoppingCartItem> cartItems)
        {
            IList<OrderItemInfo> orderItems = new List<OrderItemInfo>();
            foreach (IShoppingCartItem cartItem in cartItems)
            {
                OrderItemInfo orderItem = new OrderItemInfo(cartItem.ProductId,cartItem.Quantity,cartItem.UnitPrice);
                orderItem.Others.Add("product name", cartItem.ProductName);
                foreach (KeyValuePair<string, Object> otherPair in cartItem.Others)
                {
                    orderItem.Others.Add(otherPair);
                }

                orderItems.Add(orderItem);
            }
            return orderItems;
        }

        public static int GetNotEndOrderNumber(int userId)
        {
            return orderDAL.GetNotEndOrderNumber(userId);
        }

        public static decimal GetBuyTotalMoney(int userId, Pair<DateTime?> dateTimeRange)
        {
            return orderDAL.GetBuyTotalMoney(userId,dateTimeRange);
        }

        public static int GetEndOrderNumber(int userId)
        {
            return orderDAL.GetEndOrderNumber(userId);
        }

        public static OrderStatus PaymentStateToOrderState(PaymentState paymentState)
        {
            switch (paymentState)
            {
                case PaymentState.PendingPayment:
                    return OrderStatus.WaitPayment;
                case PaymentState.Paid:
                    return OrderStatus.InStock;
                case PaymentState.Shipped:
                    return OrderStatus.WaitReceive;
                case PaymentState.ConfirmReceipt:
                    return OrderStatus.ConfirmationReceipt;
                default:
                    throw new InvalidCastException("paymentState");
            }
        }

        public static IList<ProductInfo> GetSalesRanking(Pair<DateTime> dateTimeRang, int topNumber)
        {
            return orderDAL.GetSalesRanking(dateTimeRang, topNumber);
        }

        public static OrderItemInfo GetFirstOrderItem(int orderId){
            return orderDAL.GetFirstOrderItem(orderId);
        }
    }
}
